package com.example.androidlearning.sy8;

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.androidlearning.R;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class Sy8Activity extends AppCompatActivity {

    Button btn_read;
    Button b1;
    TextView data ;
    List<Person> personList = null;
    InputStream inputStream;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sy0801);

        btn_read = this.findViewById(R.id.xml);

        data = this.findViewById(R.id.data);

        personList = new ArrayList<>();

        b1 = findViewById(R.id.style);
        initListener();
    }

    private void initListener(){

        btn_read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.xml:
                        inputStream = getResources().openRawResource(R.raw.itcase);
                        InputStream inputStreamSAX = getResources().openRawResource(R.raw.itcase);
                        InputStream inputStreamDOM = getResources().openRawResource(R.raw.itcase);
                        if(inputStream == null){
                            Toast.makeText(Sy8Activity.this,"InputStream is null",Toast.LENGTH_SHORT).show();
                        }else{
                            List<Person> pullList = XMLParsingMethods.readXmlByPull(inputStream); //调用Pull
                            List<Person> SAXList = XMLParsingMethods.readXmlBySAX(inputStreamSAX); //调用SAX
                            List<Person> DOMList = XMLParsingMethods.readXmlByDOM(inputStreamDOM); //调用DOM
//                            personList = XMLParsingMethods.readXmlByPull(inputStream); //调用Pull
//                            personList = XMLParsingMethods.readXmlBySAX(inputStream);//调用SAX
//                            personList = XMLParsingMethods.readXmlByDOM(inputStream);//调用DOM

//                            if(pullList!=null){
//                                for(int i = 0 ;i <pullList.size();i++){
//                                    String message = "id = " + pullList.get(i).getId() + " , name = " + pullList.get(i).getName()
//                                            + " , age = " + pullList.get(i).getAge() + ".\n";
//                                    result += message;
//                                }
//                            }else{
//                                Toast.makeText(Sy8Activity.this,"persons is null",Toast.LENGTH_SHORT).show();
//                            }

//                            data.setText(result);
                            printXML(pullList, "Pull解析器");
                            printXML(SAXList,"SAX解析器");
                            printXML(DOMList,"DOM解析器");

                            XMLParsingMethods.createXmlFile(DOMList);//这里是接下来使用Pull解析器生成XML文件的方法调用
//                            XMLParsingMethods.createXmlFile(SAXList);//这里是接下来使用Pull解析器生成XML文件的方法调用
//                            XMLParsingMethods.createXmlFile(DOMList);//这里是接下来使用Pull解析器生成XML文件的方法调用
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        break;
                }
            }
        });

        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent= new Intent(Sy8Activity.this,StyleResTest.class);
                startActivity(intent);
            }
        });
    }

    private void printXML(List<Person> list, String title){
        StringBuilder result = new StringBuilder();
        result.append(title).append("\n");
        if(list != null){
            for(int i = 0 ;i <list.size();i++){
                String message = "id = " + list.get(i).getId() + " , name = " + list.get(i).getName()
                        + " , age = " + list.get(i).getAge() + ".\n";
                result.append(message);
            }
            TextView textView = new TextView(this);

            textView.setText(result.toString());
            LinearLayout layout = findViewById(R.id.sy0801_layout);
            layout.addView(textView);

        }else{
            Toast.makeText(Sy8Activity.this,"persons is null",Toast.LENGTH_SHORT).show();
        }
    }

    public static class XMLParsingMethods {

        /**【SAX解析XML文件】**/
        public static List<Person> readXmlBySAX(InputStream inputStream) {
            try {
                /**【创建解析器】**/
                SAXParserFactory spf = SAXParserFactory.newInstance();
                SAXParser saxParser = spf.newSAXParser();
                XMLContentHandler handler = new XMLContentHandler();
                saxParser.parse(inputStream, handler);
//                inputStream.close();
                return handler.getPersons();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**【DOM解析XML文件】**/
        public static List<Person> readXmlByDOM(InputStream inputStream){
            List<Person> persons = new ArrayList<>();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            try {
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document dom = builder.parse(inputStream);

                Element root = dom.getDocumentElement();
                /**【查找所有person节点】**/
                NodeList items = root.getElementsByTagName("person");
                for (int i = 0; i < items.getLength(); i++) {
                    Person person = new Person();

                    /**【得到第一个person的节点】**/
                    Element personNode = (Element) items.item(i);

                    /**【获取person节点的id属性】**/
                    person.setId(new Integer(personNode.getAttribute("id")));

                    /**【获取person节点下的所有子节点（标签之间的空白节点和name/age节点）】**/
                    NodeList childsNodes = personNode.getChildNodes();

                    /**【遍历所有子节点】**/
                    for (int j = 0; j < childsNodes.getLength(); j++) {
                        Node node = (Node) childsNodes.item(j);

                        /**【判断是否为元素类型】**/
                        if(node.getNodeType() == Node.ELEMENT_NODE){
                            Element childNode = (Element) node;
                            /**【判断是否是name元素】**/
                            if ("name".equals(childNode.getNodeName())) {
                                /**【获取name元素下的text节点，然后从text节点获取数据】**/
                                person.setName(childNode.getFirstChild().getNodeValue());
                                /**【判断是否是age元素】**/
                            }else if("age".equals(childNode.getNodeName())){
                                /**【获取age元素下的text节点，然后从text节点获取数据】**/
                                person.setAge(new Short(childNode.getFirstChild().getNodeValue()));
                            }
                        }
                    }
                    persons.add(person);
                }
//                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return persons;
        }
        /**【Pull解析器解析XML文件】**/
        public static List<Person> readXmlByPull(InputStream inputStream){
            XmlPullParser parser = Xml.newPullParser();
            try {
                parser.setInput(inputStream,"UTF-8");
                int eventType = parser.getEventType();

                Person currenPerson = null;
                List<Person> persons = null;

                while(eventType != XmlPullParser.END_DOCUMENT){
                    switch (eventType){
                        case XmlPullParser.START_DOCUMENT:/**【文档开始事件】**/
                            persons = new ArrayList<>();
                            break;
                        case XmlPullParser.START_TAG:/**【元素（即标签）开始事件】**/
                            String name = parser.getName();
                            if(name.equals("person")){
                                currenPerson = new Person();
                                currenPerson.setId(new Integer(parser.getAttributeValue(null,"id")));
                            }else if(currenPerson !=null){
                                if(name.equals("name")){/**【判断标签名（元素名）是否为name】**/
                                    currenPerson.setName(parser.nextText());/**【如果后面是text元素，即返回它的值】**/
                                }else if(name.equals("age")){
                                    currenPerson.setAge(Integer.valueOf(parser.nextText()));
                                }
                            }
                            break;
                        case XmlPullParser.END_TAG:/**【元素结束事件】**/
                            if(parser.getName().equalsIgnoreCase("person") && currenPerson != null){
                                persons.add(currenPerson);
                                currenPerson = null;
                            }
                            break;
                    }
                    eventType = parser.next();
                }
//                inputStream.close();
                return persons;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        /**【使用Pull解析器生成XML文件内容】**/
        public static String WriteXML(List<Person> persons, BufferedWriter writer ){
            XmlSerializer serializer = Xml.newSerializer();
            try {
                serializer.setOutput(writer);
                serializer.startDocument("UTF-8",true);

                /**【第一个参数为命名空间，不使用命名空间可以设置为null】**/
                serializer.startTag("","persons");
                /**【XML文件中要生成的内容】**/
                for(Person person : persons){
                    serializer.startTag("","person");
                    serializer.attribute("", "id", String.valueOf(person.getId()) );

                    serializer.startTag("","name");
                    serializer.text(person.getName());
                    serializer.endTag("","name");

                    serializer.startTag("","age");
                    serializer.text(String.valueOf(person.getAge()));
                    serializer.endTag("","age");

                    serializer.endTag("","person");
                }
                serializer.endTag("","persons");
                serializer.endDocument();
                return writer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**【生成XML文件代码】**/
        public static void createXmlFile(List<Person> persons){
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                try {
                    File sdCard = Environment.getExternalStorageDirectory();
                    File xmlFile = new File(sdCard + File.separator + "testFolder/" + "myitcast.xml");
                    FileOutputStream outStream =  new FileOutputStream(xmlFile);
                    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outStream , "UTF-8");
                    BufferedWriter writerFile = new BufferedWriter(outputStreamWriter);

                    WriteXML(persons,writerFile);
                    writerFile.flush();
                    writerFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
